from tools.virtual_key_code import get_key_state
from bdtime import tt
from tools.utils import Key
from copy import deepcopy
from bdtime import Time
import os
import json
from tools.remove_temp_file import remove_path
from tools.mouse_state_recorder import DefaultArgs


kk = Key()


class KeyStateRecorder:
    def __init__(self, frames=DefaultArgs.frames, tt=None):
        self.frames = frames
        self.save_dir = os.path.join(*['..', 'tempdir', 'recorded_states', 'key'])

        self.targets = ['w', 's', 'a', 'd', 'f', '1', '2', '3', '4', 'ctrl', 'shift', 'space', 'esc', 'f1']
        self.recorded_states = []

        self.states = dict(zip(self.targets, [0] * len(self.targets)))
        self.is_recording = False

        self.tt = tt

        self.init_states()

    def init_states(self):
        self.states = dict(zip(self.targets, [0] * len(self.targets)))

    def record(self, until='alt + x'):
        tt = self.tt if self.tt else Time()

        self.is_recording = True
        # recorded_states = []
        while True:
            if self.is_recording and tt.stop(until, raise_error=False):
                break

            tt.sleep(1 / self.frames)

            times = 0
            for key in self.targets:
                state = get_key_state(key)
                if state:
                    self.states[key] = 1
                    # self.press(key)
                    times += 1
                else:
                    self.states[key] = 0
                    # self.release(key)

            if times:
                self.states.update({'time': tt.now()})
                self.recorded_states.append(deepcopy(self.states))

        self.is_recording = False
        # show_ls(recorded_states)
        # show_ls(self.recorded_states)
        return self.recorded_states

    def play(self, recorded_states=None, speed=1):
        # keyboard.play()
        if not recorded_states:
            recorded_states = self.recorded_states

        self.init_states()

        if speed != 1:
            assert speed, 'speed不能为0!'
            for state in recorded_states:
                state['time'] = state['time'] / speed

        tt = Time()
        for state in recorded_states:
            if tt.stop('alt + x'):
                break

            while tt.now() < state['time']:
                # print(tt.now(), '------', state)
                tt.sleep(1 / self.frames)
                continue

            print(state)

            # ks = [k for k, v in state.items() if v != 0]
            for k, v in state.items():
                if k == 'time':
                    continue

                if v:
                    self.press(k)
                else:
                    self.release(k)

    def press(self, key):
        if self.states[key]:
            return

        kk.press(key)
        self.states[key] = 1

    def release(self, key):
        if not self.states[key]:
            return

        kk.release(key)
        self.states[key] = 0

    def stop_record(self):
        pass

    def save_record(self, file_name: str = ""):
        os.makedirs(self.save_dir, exist_ok=True)
        data = json.dumps(self.recorded_states, indent=4)
        timestamp = tt.get_current_beijing_time_str(tt.common_date_time_formats.ms_int[-8:])

        file_name = file_name if file_name else f'recorded_states__{timestamp}.json'

        file_path = os.path.join(self.save_dir, file_name)
        with open(file_path, 'w+') as f:
            f.write(data)
        return file_path

    def remove_all_recorded_states(self):
        remove_path(self.save_dir, keep_external_folder=True)


def run(save_file_name: str = "", play=False):
    key_state_recorder = KeyStateRecorder()

    key_state_recorder.record()

    # save_file_name = 'key_state_recorder__1'
    if save_file_name:
        key_state_recorder.save_record(file_name=save_file_name)

    if play:
        tt.sleep(1)
        key_state_recorder.play(speed=3)


def main():
    run()
    # key_state_recorder = KeyStateRecorder()
    # recorded_states = key_state_recorder.record()
    #
    # # print('len ---', len(key_state_recorder.recorded_states))
    # # show_ls(key_state_recorder.recorded_states)
    #
    # # key_state_recorder.save_record()
    #
    # # key_state_recorder.remove_all_recorded_states()
    #
    # tt.sleep(1)
    # key_state_recorder.play(speed=3)

    pass


if __name__ == '__main__':
    main()
    # k = 'a'
    #
    # tt.sleep(2)
    # # kk.press(k)
    # keyboard.press(k)
    #
    # tt.sleep(0.5)
    # print('get_key_state(k)', get_key_state(k))
    # print('is_pressed(k)', keyboard.is_pressed(k), keyboard.is_pressed('s'))
    #
    # tt.sleep(5)
    # # kk.release(k)
    # keyboard.release(k)
    #
    # exit()

